package com.jiutong.meipenggang.utils;

import android.text.TextUtils;
import android.util.Base64;

import com.jiutong.meipenggang.common.Constants;

import java.net.URLEncoder;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by suxi on 2017/12/7.
 */

public class EncryptUtil {

    /**
     * 签名算法
     */
    public static final String SIGNATURE_ALGORITHM = "SHA384withRSA";
    public static final String PRAVITEKEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAME7p+1BrGlbRjEWc1QQs38dymXdHOmazgkxFOgmgD/xYzLLPwYWyipxYtxGgvwmOyKyPMVV5oIy8+mNdkAad1jRzKSWUQ3j8NnlMabqpl+4raai0iouEwG51A3zyc0ShKjWz+vHHzp4rs6YsKA+F3c9y00AUPd2aAlGe/sv7nfJAgMBAAECgYAY3gaEX/lCLb7gvlTlMqkG6NyNM2FvJr7xK+HW5m2GzRfJB6L6s6Acyi7Azko5DOp7UpjDhIR/qPL+0XewVDebe0a51/4GTB+opqsBThnWxQud8iISzhRVKlqB09nttDtPajhk15zYH9RLI8TVmivzrvLbtKAs7MQR+jEfQqFDAQJBAOieXaEPt+d+GDp4IEO3/hp51n7QqHAlH9c/klG+y9dGHl4IXG6TsP4OBbR0rQGkHK/+/8pTalgAp3e3TVGD3lECQQDUp9awig29nkJ5/Nm51kEc8jhCmfk1PnaI7Rvyyk4UyUQwDwpG1AddO71Lb7D5gTMBq66pJ5LrBAscUWnyEcv5AkB02qk6MYU22xccuB+tJQ6XCkGALx2OSHf4T00Xl3sax3SV1ClquvKcjTq8bihCvMhUeQrR/plbX+jAsOo8WrwhAkByzuJTkVT1yFlvbplFgWzJ6eOB4YrvufdY2Vo7bAlXo4mSwKv1rUcEiNobvgM30Q7umffEDz98bkRpV3LxY7ZRAkEAlerUJtRAW5Q+flI6pTYSZAncHJcdeniNcal9Y/RyyG0uxqwdW+BO+z2XbjxCSdAKTyf3j2L23C7YvjnsmcbIAA==";
    public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";//加密填充方式

    public static String encryptByMD5AndRSA(Map<String, Object> files) throws Exception {

        //获取信息摘要 - 参数字典排序后字符串
        String orderFielsToString = getOrderByLexicographic(files);
//        Logger.d("待加密字符串：" + orderFielsToString);
        try {
            String encryptByMD5 = encryptByMD5(orderFielsToString);
//            Logger.d("字符串MD5加密后：" + encryptByMD5);

            byte[] endResult = encryptByPrivateKey(encryptByMD5.getBytes());

            return Base64.encodeToString(endResult, Base64.NO_WRAP);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new NoSuchAlgorithmException("签名错误！");
        }
    }

    public static String encryptByMD5(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(string.getBytes());
            String result = "";
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result += temp;
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 私钥加密
     *
     * @param data 待加密数据
     * @return byte[] 加密数据
     */
    public static byte[] encryptByPrivateKey(byte[] data) throws Exception {
        byte[] keyBytes = Base64.decode(PRAVITEKEY, Base64.DEFAULT);

        // 得到私钥
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey keyPrivate = kf.generatePrivate(keySpec);

        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(keyPrivate);
        signature.update(data);

        // 数据加密
//        Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);
//        cipher.init(Cipher.ENCRYPT_MODE, keyPrivate);
//        return cipher.doFinal(data);
        return signature.sign();
    }

    /**
     * 获取参数的字典排序
     *
     * @param maps 参数key-value map集合
     * @return String 排序后的字符串
     */
    public static String getOrderByLexicographic(Map<String, Object> maps) {
        return splitParams(lexicographicOrder(getParamsName(maps)), maps);
    }


    /**
     * 获取参数名称 key
     *
     * @param maps 参数key-value map集合
     * @return
     */
    private static List<String> getParamsName(Map<String, Object> maps) {
        List<String> paramNames = new ArrayList<String>();
        for (Map.Entry<String, Object> entry : maps.entrySet()) {
            paramNames.add(entry.getKey());
        }
        return paramNames;
    }


    /**
     * 参数名称按字典排序
     *
     * @param paramNames 参数名称List集合
     * @return 排序后的参数名称List集合
     */
    private static List<String> lexicographicOrder(List<String> paramNames) {
        Collections.sort(paramNames);
        return paramNames;
    }

    /**
     * 拼接排序好的参数名称和参数值
     *
     * @param paramNames 排序后的参数名称集合
     * @param maps       参数key-value map集合
     * @return String 拼接后的字符串
     */
    private static String splitParams(List<String> paramNames, Map<String, Object> maps) {
        StringBuilder paramStr = new StringBuilder();
        for (String paramName : paramNames) {
            for (Map.Entry<String, Object> entry : maps.entrySet()) {
                if (paramName.equals(entry.getKey()) && !TextUtils.isEmpty(String.valueOf(entry.getValue()))) {
                    paramStr.append(paramName + "=" + String.valueOf(entry.getValue()) + "&");
                }
            }
        }
        return paramStr.toString().substring(0, paramStr.length() - 1);
    }

    public static String encrypt3DES(String input) {
        return com.shove.security.Encrypt.encrypt3DES(input, Constants.KEY_DATA);
    }


    public static String encryptGesture3DES(String input) {
        return com.shove.security.Encrypt.encrypt3DES(input, Constants.GESTURE_KEY);
    }


}
